var WebSocketLibrary =
{
    $webSocketManager:
    {
        onOpen: null,
        onMessage: null,
        onError: null,
        onClose: null,
        lastId: 0,
        instances: []
    },
    WebSocketSetOpenCallback: function(callback)
    {
        webSocketManager.onOpen = callback;
    },
    WebSocketSetMessageCallback: function(callback)
    {
        webSocketManager.onMessage = callback;
    },
    WebSocketSetErrorCallback: function(callback)
    {
        webSocketManager.onError = callback;
    },
    WebSocketSetCloseCallback: function(callback)
    {
        webSocketManager.onClose = callback;
    },
    WebSocketOpen: function (url)
    {
        var id = ++webSocketManager.lastId;
        var ws = new WebSocket(UTF8ToString(url));
        ws.binaryType = 'arraybuffer';
        ws.onopen = function(ev)
        {
            Module.dynCall_vi(webSocketManager.onOpen, id);
        };
        ws.onmessage = function(ev)
        {
            var array = new Uint8Array(ev.data);
            var buffer = _malloc(array.length);
            writeArrayToMemory(array, buffer);
            try
            {
                Module.dynCall_vii(webSocketManager.onMessage, id, buffer);
            }
            finally
            {
                _free(buffer);
            }
        };
        ws.onerror = function(ev)
        {
            try
            {
                Module.dynCall_vii(webSocketManager.onError, id, 0);
            }
            finally
            {
                _free(buffer);
            }
        };
        ws.onclose = function(ev)
        {
            Module.dynCall_vi(webSocketManager.onClose, id);
            webSocketManager.instances[id] = null;
        };
        webSocketManager.instances[id] = ws;
        return id;
    },
    WebSocketSend: function (id, bufferPtr, length)
    {
        var ws = webSocketManager.instances[id];
        if (!ws) return -1;
        if (ws === null) return -2;
        if (ws.readyState !== 1) return -3;
        ws.send(buffer.slice(bufferPtr, bufferPtr + length));
        return 0;
    },
    WebSocketClose: function(id)
    {
        var ws = webSocketManager.instances[id];
        if (!ws) return;
        if (ws === null) return;
        if (ws.readyState < 2)
        {
            ws.close(1000);
            webSocketManager.instances[id] = null;
        }
    },
    WebSocketState: function (id)
    {
        var ws = webSocketManager.instances[id];
        if (!ws) return -1;
        if (ws === null) return 3;
        return ws.readyState;
    }
};
autoAddDeps(WebSocketLibrary, '$webSocketManager');
mergeInto(LibraryManager.library, WebSocketLibrary);